package com.cdel.akka.AkkainJAVA.future;

import java.util.Random;

import scala.concurrent.Future;
import akka.actor.ActorSystem;
import akka.dispatch.Futures;
import akka.dispatch.OnComplete;
import akka.dispatch.OnFailure;
import akka.dispatch.OnSuccess;

public class FutureTest {

	//这个例子使用Futures.future创建了一个异步的代码执行块.然后可以指定Future的onSuccess和onFailure等状态的响应.当Future执行到这些状态的时候,就会执行响应代码中的方法.
	//比如这个例子中,在Futures.future异步执行体中随机的返回正常结果或抛出异常.然后增加了future成功和失败的两个状态的处理,分别是打印正常的结果和打印失败的异常.
	//当我们执行这段代码后,由于异步代码块中休眠了10毫秒,因此必然会先打印这个地方是外面这句话,这也证明了这些代码全是异步执行的.然后随机的会打印成功或失败的信息.
    public static void main(String[] args) throws Exception {
        final ActorSystem system = ActorSystem.create("helloakka");

        /*通过Futures的静态方法future创建一个Future类.入参就是一个异步的计算*/
        Future<String> f = Futures.future(() -> {
        	Thread.sleep(10);
            if (new Random(System.currentTimeMillis()).nextBoolean()){
                return "Hello" + "World!";
            }else {
                throw new IllegalArgumentException("参数错误");
            }
        }, system.dispatcher())
        //除了可以给Future设定onSuccess onFailure和onComplete外,还有一个很有用的功能就是可以设定Future的后续操作,也就是多个Future联合操作.
        //当执行完f的onSuccess方法后,接下来会执行第一个andThen中所指定的异步操作,而后继续执行第二个andThen中的操作.通过这样的操作,就可以形成一条异步调用链.
        //除此之外,Future还有很多有用的方法,比如foreach transform map filter等等.这些个方法和JDK1.8中的StreamAPI非常的相似.
        .andThen(new OnComplete<String>() {
            @Override
            public void onComplete(Throwable failure, String success) throws Throwable {
                System.out.println("这里是andThen");
            }
        }, system.dispatcher())
        .andThen(new OnComplete<String>() {
            @Override
            public void onComplete(Throwable failure, String success) throws Throwable {
                System.out.println("这里是andThen2");
            }
        }, system.dispatcher());
        f.onSuccess(new PrintResult<String>(), system.dispatcher());
        f.onFailure(new FailureResult(), system.dispatcher());
        System.out.println("这个地方是外面");
    }

    public final static class PrintResult<T> extends OnSuccess<T> {
        @Override public final void onSuccess(T t) {
            System.out.println(t);
        }
    }

    public final static class FailureResult extends OnFailure {
        @Override
        public void onFailure(Throwable failure) throws Throwable {
            System.out.println("进入错误的处理");
            failure.printStackTrace();
        }
    }

}